#include <vector>
#include <algorithm>
#include <functional>
#include <numeric>
#include <iostream>


template <typename T>
class DataContainer {
public:
    // 添加数据：简单的数据添加，为接下来的函数式操作准备数据集
    void add(const T& item) {
        data_.push_back(item);
    }

    // 映射：应用一个函数到数据集中的每个元素。函数式编程的优势在于能够将处理逻辑作为一等公民传递，提高代码的通用性和可复用性
    template <typename Func>
    void map(Func func) {
        std::transform(data_.begin(), data_.end(), data_.begin(), func);
    }

    // 筛选：根据给定的谓词函数返回满足条件的元素集合。这种方式使数据处理非常灵活，易于调整和扩展筛选条件
    template <typename Predicate>
    DataContainer<T> filter(Predicate pred) {
        DataContainer<T> result;
        std::copy_if(data_.begin(), data_.end(), std::back_inserter(result.data_), pred);
        return result;
    }

    // 聚合：使用一个归约函数来转换和合并整个数据集。这种方法允许灵活定义如何合并数据元素，支持从简单的总和到更复杂的统计模型
    template <typename ReduceFunc>
    T aggregate(T initVal, ReduceFunc func) {
        return std::accumulate(data_.begin(), data_.end(), initVal, func);
    }

    // 获取数据用于演示或测试
    std::vector<T> getData() const {
        return data_;
    }

private:
    std::vector<T> data_;
};

int main() {
    DataContainer<int> data;
    data.add(1);
    data.add(2);
    data.add(3);
    data.add(4);
    data.add(5);

    // 映射：将每个元素乘以2。此操作展示了如何简捷地应用转换逻辑到数据集的每一个元素
    data.map([](int x) -> int { return x * 2; });

    // 筛选：选择大于5的元素。筛选操作的优势在于能够灵活快速地调整条件，应对不同的数据筛选需求
    auto filtered = data.filter([](int x) -> bool { return x > 5; });

    // 聚合：计算总和。通过聚合，我们可以非常灵活地定义整个数据集如何被合并处理，支持各种复杂的统计聚合功能
    int sum = filtered.aggregate(0, [](int acc, int x) -> int { return acc + x; });

    std::cout << "Sum of elements > 5 after mapping: " << sum << std::endl;
    return 0;
}